import org.apache.xmlrpc.XmlRpcRequest;
import org.apache.xmlrpc.client.AsyncCallback;

/**
 * CallBackHandler This class runs on the master. A reference is sent to the
 * slaves. When the salves are done with computation, they call handleResult of
 * the CallBackHander reference. Master keeps checking callbackhandler
 * 
 * @author Praneeth Pulusani
 * 
 */
public class CallBackHandler implements AsyncCallback {
	//class variables
	int[] result;
	int widthmatrix1;
	int callbackcounter;
	int columnscounter;
	boolean debug1 = false;
	boolean debug2 = false;

	/**
	 * Constructor
	 * Initializes to have enough space for the resultant matrix
	 * @param widthmatrix1 dimension of first matrix
	 * @param widthmatrix2 dimension of second matrix
	 */
	public CallBackHandler(int widthmatrix1, int widthmatrix2) {
		this.widthmatrix1 = widthmatrix1;
		result = new int[widthmatrix1 * widthmatrix2];
		callbackcounter = 0;
		columnscounter = 0;
	}

	@Override
	public void handleResult(XmlRpcRequest pRequest, Object pResult) {

		int numColumnsReceived = ((Object[]) pResult).length;
		//For all the columns received, traverse through them and add the elements to the result matrix
		for (int i = 0; i < numColumnsReceived; i++) {
			int[] currentColumn = (int[]) (((Object[]) pResult)[i]);
			int columnID = currentColumn[0];
			int columnLength = widthmatrix1;
			for (int j = 0; j < columnLength; j++) {
				result[j * widthmatrix1 + columnID] = currentColumn[j + 1];
			}

		}
		//update counter in a synchronized block so that all received columns will be accounted.
		synchronized (this) {
			callbackcounter++;
			columnscounter = columnscounter + numColumnsReceived;

			if (debug1) {
				System.out.println("Number of columns received "
						+ numColumnsReceived);
				System.out
						.println("Number of columns received (Cumulative total) "
								+ columnscounter);
				System.out.println("Client's callback was called "
						+ callbackcounter + " times");

			}
		}

	}
	/**
	 * handleError
	 * If there is an error receiving data from xml rpc slaves, print error and exit
	 */
	@Override
	public void handleError(XmlRpcRequest pRequest, Throwable pError) {
		pError.printStackTrace();
		System.exit(-1);

	}
	/**
	 * getResult()
	 * Return the result matrix. Called by Master
	 * @return result matrix
	 */
	public int[] getResult() {
		return result;
	}
	
	/**
	 * getCounter()
	 * Returns number of columns received. Called by master to check if all the columns are received
	 * @return number of columns received
	 */
	public int getCounter() {
		return columnscounter;
	}

}
